﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using TCC_Hotel.Serviços.BDServices;
using TCC_Hotel.Entidades;
using TCC_Hotel.Serviços.OtherServices;
using System.Text;
using System.Drawing;
using System.Threading;

namespace TCC_Hotel.Apresentacao.Reservas
{
    public partial class MapaReservas : System.Web.UI.Page
    {       
        ApartamentoService servico = new ApartamentoService();
        ReservaService servico_Reservas = new ReservaService();
        List<Reserva_Particular> listaReservas_Particulares;
        List<Reserva_Faturada> listaReservas_Faturadas;
        List<DiaNomeReserva> listaDiasReservas;

        /// <summary>
        /// Carregamento da página
        /// </summary>
        protected void Page_Load(object sender, EventArgs e)
        {
            //Recupera o usuario corrente
            string usuario = Request.ServerVariables["AUTH_USER"].ToString();
            LoginService servico_Login = new LoginService();
            //Verifica permissao ao acesso da página
            if (!servico_Login.RecuperarPermissaoCache(usuario).Reservas)
            {
                //Redireciona para a pagina inicial
                Response.Redirect("~/");
            }

            if (!IsPostBack)
            {
                //limpa os chaches existentes para pegar os dados mais atualizados
                HttpContext.Current.Cache.Remove("Lista_Reserva_Particular");                
                HttpContext.Current.Cache.Remove("Lista_Reserva_Faturada");

                //se ja vier selecionado, mostra o apartamento corrente
                if (Request.Params["apartamentoCorrente"] != null && Request.Params["numeroHospedeCorrente"] != null)
                {
                    ddlNumeroHospedes.SelectedValue = Request.Params["numeroHospedeCorrente"];
                }
                else
                {
                    ddlNumeroHospedes.SelectedValue = "1";
                }                

                FiltrarApartamentos();

                //se ja vier selecionado, mostra o apartamento corrente
                if (Request.Params["apartamentoCorrente"] != null && Request.Params["numeroHospedeCorrente"] != null)
                {
                    ddlApartamentos.SelectedValue = servico.ListarApartamentosCache().Where(i => i.Nome == Request.Params["apartamentoCorrente"]).FirstOrDefault().Numero.ToString();
                }
                
            }
            
            //Verifica se existe um apartamento com essa quantidade de hóspede para evitar uma excessao
            if (!String.IsNullOrEmpty(ddlApartamentos.SelectedValue))
            {
                listaReservas_Particulares = servico_Reservas.ListarReservasParticularesCache().Where(i => i.Numero_Apartamento == Convert.ToInt32(ddlApartamentos.SelectedValue)).ToList();
                listaReservas_Faturadas = servico_Reservas.ListarReservasFaturadasCache().Where(i => i.Numero_Apartamento == Convert.ToInt32(ddlApartamentos.SelectedValue)).ToList();
                listaDiasReservas = servico_Reservas.ListarDiasReservas(listaReservas_Particulares, listaReservas_Faturadas);
            }
                     
        }

        /// <summary>
        /// Evento quando altera o apartamento. deve-se mostrar os dias que estao reservados ou livres no calendario
        /// </summary>
        protected void ddlApartamentos_SelectedIndexChanged(object sender, EventArgs e)
        {
            //Verifica se existe um apartamento com essa quantidade de hóspede para evitar uma excessao
            if (!String.IsNullOrEmpty(ddlApartamentos.SelectedValue))
            {
                listaReservas_Particulares = servico_Reservas.ListarReservasParticularesCache().Where(i => i.Numero_Apartamento == Convert.ToInt32(ddlApartamentos.SelectedValue)).ToList();
                listaReservas_Faturadas = servico_Reservas.ListarReservasFaturadasCache().Where(i => i.Numero_Apartamento == Convert.ToInt32(ddlApartamentos.SelectedValue)).ToList();
                listaDiasReservas = servico_Reservas.ListarDiasReservas(listaReservas_Particulares, listaReservas_Faturadas);
            }
         
           
        }

        /// <summary>
        /// Coloca os dias escolhidos pelo usuario nos textbox correspondentes
        /// </summary>       
        protected void cldReservas_SelectionChanged(object sender, EventArgs e)
        {
            lblErro.Visible = false;

            //se data inicial vazia coloca o dia clicado nela
            if (String.IsNullOrEmpty(txtDataInicial.Text))
            {
                txtDataInicial.Text = Convert.ToString(cldReservas.SelectedDate.ToString("dd/MM/yyyy"));
                
            }
            // se data final vazia coloca o dia clicado nela
            else if (!String.IsNullOrEmpty(txtDataInicial.Text) && String.IsNullOrEmpty(txtDataFinal.Text))
                txtDataFinal.Text = Convert.ToString(cldReservas.SelectedDate.ToString("dd/MM/yyyy"));

            // senão coloca na data inicial e zera a data final
            else
            {
                txtDataInicial.Text = Convert.ToString(cldReservas.SelectedDate.ToString("dd/MM/yyyy"));
                txtDataFinal.Text = null;
            }
            cldReservas.SelectedDate = new DateTime();
           
        }

        /// <summary>
        /// Evento que chamará a tela de cadastro de reserva para hóspede particular
        /// </summary>
        protected void btnReservarParticular_Click(object sender, EventArgs e)
        {
            ComumServices comum = new ComumServices();
            lblErroFiltro.Visible = false;
            //preenche a lista obrigatoria para verificar se todos os campos obrigatorios fora preenchidos
            List<string> listaObrigatoria = new List<string>() 
            { 
                txtDataInicial.Text,
                txtDataFinal.Text,
                ddlApartamentos.SelectedValue
            };

            //verifica se algum campo obrigatorio nao foi preenchido
            if (!comum.ValidaCamposObrigatorios(listaObrigatoria))
            {
                lblErro.Text = "Campo(s) obrigatório(s) em branco";
                lblErro.Visible = true;
                return;
            }
            else
            {
                lblErro.Visible = false;
            }

             //verifica a data de fim nao eh menor que a de começo
            if (!servico_Reservas.VerificaDatas(txtDataInicial.Text,txtDataFinal.Text))
            {
                lblErro.Text = "Data final menor que a data inicial ou é uma data passada";
                lblErro.Visible = true;
                return;
            }
            else
            {
                lblErro.Visible = false;
            }

            //verifica a data de fim nao eh menor que a de começo
            if (!servico_Reservas.VerificaDisponibilidade(txtDataInicial.Text, txtDataFinal.Text, listaDiasReservas))
            {
                lblErro.Text = "Período desejado não está disponível";
                lblErro.Visible = true;
                return;
            }
            else
            {
                lblErro.Visible = false;
            }
            //Redireciona para a pagina de detalhes correspondente com o numero como parametro
            Response.Redirect("~/Apresentacao/Reservas/EfetuarReservaHospedeParticular.aspx?numeroHospedes=" + ddlNumeroHospedes.SelectedValue + "&apartamento=" + ddlApartamentos.SelectedItem + "&numeroApartamento=" + ddlApartamentos.SelectedValue  + "&dataInicial=" + txtDataInicial.Text + "&dataFinal=" + txtDataFinal.Text);

        }

        /// <summary>
        /// Atualiza o dropdown de apartamentos
        /// </summary>
        protected void FiltrarApartamentos()
        {
            //popular o dropdown estados
            ddlApartamentos.DataSource = servico.ListarApartamentosCache().Where(i => i.QntMaximaHospedes == Convert.ToInt32(ddlNumeroHospedes.SelectedValue));
            ddlApartamentos.DataTextField = "Nome";
            ddlApartamentos.DataValueField = "Numero";
            ddlApartamentos.DataBind();
            
        }

        /// <summary>
        /// Evento de mudança do numero de hospedes
        /// </summary>
        protected void ddlNumeroHospedes_SelectedIndexChanged(object sender, EventArgs e)
        {
            FiltrarApartamentos();

            //Verifica se existe um apartamento com essa quantidade de hóspede para evitar uma excessao
            if (!String.IsNullOrEmpty(ddlApartamentos.SelectedValue))
            {
                listaReservas_Particulares = servico_Reservas.ListarReservasParticularesCache().Where(i => i.Numero_Apartamento == Convert.ToInt32(ddlApartamentos.SelectedValue)).ToList();
                listaReservas_Faturadas = servico_Reservas.ListarReservasFaturadasCache().Where(i => i.Numero_Apartamento == Convert.ToInt32(ddlApartamentos.SelectedValue)).ToList();
                listaDiasReservas = servico_Reservas.ListarDiasReservas(listaReservas_Particulares, listaReservas_Faturadas);
            }
            //caso não houver nenhum apartamento para o determinado número de hósede, ele carrega um calendar vazio
            else
            {
                listaReservas_Particulares = servico_Reservas.ListarReservasParticularesCache().Where(i => i.Numero_Apartamento == 0).ToList();
                listaReservas_Faturadas = servico_Reservas.ListarReservasFaturadasCache().Where(i => i.Numero_Apartamento == 0).ToList();
                listaDiasReservas = servico_Reservas.ListarDiasReservas(listaReservas_Particulares, listaReservas_Faturadas);
            
            }
            //limpa os filtros
            txtPeriodoInicial.Text = null;
            txtPeriodoFinal.Text = null;
        }

    
        /// <summary>
        /// Evento que é executado para cada dia no calendário
        /// </summary>
         protected void cldReservas_DayRender(object sender, DayRenderEventArgs e)
        {
            DiaNomeReserva diaNome = null;
            Literal literal = new Literal();
            StringBuilder sbHtml = new StringBuilder();

            //pega a reserva desta data
            if (listaDiasReservas != null)
            {
                diaNome = listaDiasReservas.Where(i => i.Data == e.Day.Date).FirstOrDefault();
            }
            else
            {
                diaNome = null;
            }

            //verifica se para esta data existe uma reserva
            if (diaNome != null)
            {               
                    sbHtml.Append("<br />");

                    sbHtml.Append(diaNome.Nome + "<br />");

                    sbHtml.Append("<br />");

                    literal.Text = sbHtml.ToString();

                    e.Cell.Controls.Add(literal);

                    if (diaNome.TipoHospede == 1)
                         e.Cell.BackColor = Color.OrangeRed; 
                    else
                         e.Cell.BackColor = Color.DarkOrange;

                    if (diaNome.NoHotel)
                    {
                        e.Cell.BackColor = Color.Aquamarine;
                    }
            }
           //senao apenas pula linha para não quebrar o layout
            else
            {

                sbHtml.Append("<br /><br /><br />");

                literal.Text = sbHtml.ToString();

                e.Cell.Controls.Add(literal);
                e.Cell.BackColor = Color.GreenYellow;
            }

            
        }

         /// <summary>
         /// Evento que chamará a tela de cadastro de reserva para hóspede faturado
         /// </summary>
         protected void btnReservarFaturado_Click(object sender, EventArgs e)
         {
             ComumServices comum = new ComumServices();
             lblErroFiltro.Visible = false;
             //preenche a lista obrigatoria para verificar se todos os campos obrigatorios fora preenchidos
             List<string> listaObrigatoria = new List<string>() 
            { 
                txtDataInicial.Text,
                txtDataFinal.Text,
                ddlApartamentos.SelectedValue       
            };

             //verifica se algum campo obrigatorio nao foi preenchido
             if (!comum.ValidaCamposObrigatorios(listaObrigatoria))
             {
                 lblErro.Text = "Campo(s) obrigatório(s) em branco";
                 lblErro.Visible = true;
                 return;
             }
             else
             {
                 lblErro.Visible = false;
             }

             //verifica a data de fim nao eh menor que a de começo
             if (!servico_Reservas.VerificaDatas(txtDataInicial.Text, txtDataFinal.Text))
             {
                 lblErro.Text = "Data final menor que a data inicial ou é uma data passada";
                 lblErro.Visible = true;
                 return;
             }
             else
             {
                 lblErro.Visible = false;
             }

             //verifica a data de fim nao eh menor que a de começo
             if (!servico_Reservas.VerificaDisponibilidade(txtDataInicial.Text, txtDataFinal.Text, listaDiasReservas))
             {
                 lblErro.Text = "Período desejado não está disponível";
                 lblErro.Visible = true;
                 return;
             }
             else
             {
                 lblErro.Visible = false;
             }
             //Redireciona para a pagina correspondente com os  parametros
             Response.Redirect("~/Apresentacao/Reservas/EfetuarReservaHospedeFaturado.aspx?numeroHospedes=" + ddlNumeroHospedes.SelectedValue + "&apartamento=" + ddlApartamentos.SelectedItem + "&numeroApartamento=" + ddlApartamentos.SelectedValue + "&dataInicial=" + txtDataInicial.Text + "&dataFinal=" + txtDataFinal.Text);
         }

        /// <summary>
        /// Evento que atualiza a tabela de reservas a cada 5 segundos para manter
        /// a concistencia entre os usuarios
        /// </summary>
        protected void Timer1_Tick(object sender, EventArgs e)
         {/*
            Usado apenas para dar um reload na página e pegar os dados atualizados
           */
         }        
        /// <summary>
        /// Evento de click do botão de filtro
        /// </summary>
        protected void btnFiltrar_Click(object sender, EventArgs e)
        {
            lblErro.Visible = false;
            ComumServices comum = new ComumServices();
            List<Apartamento> listaApartamentosFiltrada = new List<Apartamento>(); ;
            int numeroHospedes;
            int.TryParse(ddlNumeroHospedes.SelectedValue, out numeroHospedes);
            string dataInicial = txtPeriodoInicial.Text;
            string dataFinal = txtPeriodoFinal.Text;

            //preenche a lista obrigatoria para verificar se todos os campos obrigatorios fora preenchidos
            List<string> listaObrigatoria = new List<string>() 
            { 
                dataInicial,
                dataFinal    
            };

            //verifica se algum campo obrigatorio nao foi preenchido
            if (!comum.ValidaCamposObrigatorios(listaObrigatoria))
            {
                lblErroFiltro.Text = "Data(s) do filtro não preenchidas corretamente";
                lblErroFiltro.Visible = true;
                return;
            }
            else
            {
                lblErroFiltro.Visible = false;
            }

            //verifica se as datas são validas
            if (txtPeriodoFinal.Text.Length < 10 || txtPeriodoInicial.Text.Length < 10)
            {
                lblErroFiltro.Text = "Datas incorretas!";
                lblErroFiltro.Visible = true;
                return;
            }
            else
            {
                lblErroFiltro.Visible = false;
            }

            //verifica a data de fim nao eh menor que a de começo
            if (!servico_Reservas.VerificaDatas(dataInicial, dataFinal))
            {
                lblErroFiltro.Text = "Data final menor que a data inicial ou é uma data passada";
                lblErroFiltro.Visible = true;
                return;
            }
            else
            {
                lblErroFiltro.Visible = false;
            }

            //filtra os apartamentos por periodo
            listaApartamentosFiltrada = servico_Reservas.FiltrarApartamentosPorPeriodo(numeroHospedes, dataInicial, dataFinal);
            
            //popular o dropdown apartamentos
            ddlApartamentos.DataSource = listaApartamentosFiltrada;
            ddlApartamentos.DataTextField = "Nome";
            ddlApartamentos.DataValueField = "Numero";
            ddlApartamentos.DataBind();

            //Verifica se existe um apartamento com essa quantidade de hóspede para evitar uma excessao
            if (!String.IsNullOrEmpty(ddlApartamentos.SelectedValue))
            {
                listaReservas_Particulares = servico_Reservas.ListarReservasParticularesCache().Where(i => i.Numero_Apartamento == Convert.ToInt32(ddlApartamentos.SelectedValue)).ToList();
                listaReservas_Faturadas = servico_Reservas.ListarReservasFaturadasCache().Where(i => i.Numero_Apartamento == Convert.ToInt32(ddlApartamentos.SelectedValue)).ToList();
                listaDiasReservas = servico_Reservas.ListarDiasReservas(listaReservas_Particulares, listaReservas_Faturadas);
            }
            //caso não houver nenhum apartamento para o determinado número de hósede, ele carrega um calendar vazio
            else
            {
                listaReservas_Particulares = servico_Reservas.ListarReservasParticularesCache().Where(i => i.Numero_Apartamento == 0).ToList();
                listaReservas_Faturadas = servico_Reservas.ListarReservasFaturadasCache().Where(i => i.Numero_Apartamento == 0).ToList();
                listaDiasReservas = servico_Reservas.ListarDiasReservas(listaReservas_Particulares, listaReservas_Faturadas);

            }
        }

        /// <summary>
        /// Evento de click do botão de limpar o filtro
        /// </summary>
        protected void btnLimpar_Click(object sender, EventArgs e)
        {
            lblErro.Visible = false;
            txtPeriodoInicial.Text = null;
            txtPeriodoFinal.Text = null;
            lblErroFiltro.Visible = false;
            //popular o dropdown estados
            ddlApartamentos.DataSource = servico.ListarApartamentosCache().Where(i => i.QntMaximaHospedes == Convert.ToInt32(ddlNumeroHospedes.SelectedValue));
            ddlApartamentos.DataTextField = "Nome";
            ddlApartamentos.DataValueField = "Numero";
            ddlApartamentos.DataBind();

            //Verifica se existe um apartamento com essa quantidade de hóspede para evitar uma excessao
            if (!String.IsNullOrEmpty(ddlApartamentos.SelectedValue))
            {
                listaReservas_Particulares = servico_Reservas.ListarReservasParticularesCache().Where(i => i.Numero_Apartamento == Convert.ToInt32(ddlApartamentos.SelectedValue)).ToList();
                listaReservas_Faturadas = servico_Reservas.ListarReservasFaturadasCache().Where(i => i.Numero_Apartamento == Convert.ToInt32(ddlApartamentos.SelectedValue)).ToList();
                listaDiasReservas = servico_Reservas.ListarDiasReservas(listaReservas_Particulares, listaReservas_Faturadas);
            }
        }      
    }
}